home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.09 Sep 89 / World Source / MapInfo.c < prev   
Encoding:
C/C++ Source or Header  |  1989-06-15  |  4.8 KB  |  234 lines  |  [TEXT/KAHL]

  1.  
  2. /*
  3.  * This is a simple program to demonstrate
  4.  * extracting information from the Macintosh
  5.  * parameter RAM and displaying the current
  6.  * latitude, longitude, and time-zone offset.
  7.  * Note that the format and manner of storage
  8.  * of this data have not been published by
  9.  * Apple.
  10.  *
  11.  * This program is copyright © 1988, 1989
  12.  * by MacTutor magazine.  You may incorpor-
  13.  * ate portions of this program in your
  14.  * applications without restriction.
  15.  *
  16.  * Compile using Think C, V3.0.
  17.  *
  18.  * Written by Martin Minow and Mike Carleton
  19.  */
  20.  
  21. #include    <stdio.h>
  22.  
  23. /*
  24.  * Define the "Read parameter ram" trap and
  25.  * the offset in the parameter ram where the
  26.  * map is stored.  This information doesn't
  27.  * seem to be written down anywhere.
  28.  */
  29. #define    _ReadXPRam    0xA051
  30. #define    Map_Offset    0xE4    /* Ram offset    */
  31.  
  32. /*
  33.  * This structure defines the location
  34.  * currently set by the Map Cdev.
  35.  *
  36.  * Latitude and longitude are long integers
  37.  * specifying the fraction of the circle:
  38.  *      1 degree East == 0x000308B9
  39.  *      1 degree West == 0xFFFCF747
  40.  * All values are possible for longitude,
  41.  * while latitude is constrained to ± 90°.
  42.  *
  43.  * Only the low-order three bytes of timezone
  44.  * are used.  The value is the number of
  45.  * seconds offset from UTC, East is positive,
  46.  * West negative.
  47.  */
  48. #ifdef Use_Script_Manager
  49. #include <ScriptMgr.h>
  50.  
  51. typedef struct {
  52.     Fract    latitude;
  53.     Fract    longitude;
  54.     union {
  55.         char    dlsDelta;
  56.         long    gmtDelta;
  57.     } gmtFlags;
  58. } MachineLocation;
  59.  
  60. MachineLocation    info;
  61. pascal void    ReadLocation(MachineLocation *);
  62. #else
  63. typedef struct {
  64.     long    latitude;
  65.     long    longitude;
  66.     long    timezone;
  67. } MapDatum;
  68.     
  69. MapDatum    info;    
  70. #endif
  71.  
  72. void        main(void);
  73. void        dms(long, char *, char *);
  74. void        hms(long, char *);
  75. OSErr        read_param_ram(void *, int, int);
  76.  
  77. void        printf(char *, ...);
  78. int            fgetc(FILE *);
  79.  
  80. void
  81. main()
  82. {
  83.     OSErr        status;
  84.  
  85.     /*
  86.      * This is a test for divide rounding.
  87.      * It should yield 180°00'00" W.
  88.      */
  89.     dms(0x80000000L, "Test", "EW");
  90.     /*
  91.      * Loop through here until the user
  92.      * types 'q' -- this lets you run the Map
  93.      * Cdev at the same time to see how
  94.      * location and timezone changes affect
  95.      * the data.
  96.      */
  97.     do {
  98.  
  99. #ifdef Use_Script_Manager
  100.         ReadLocation(&info);
  101.         dms(info.latitude, "Latitude", "NS");
  102.         dms(info.longitude,
  103.                 "Longitude", "EW");
  104.         hms(info.gmtFlags.gmtDelta, "Zone");
  105. #else
  106.         status = read_param_ram(
  107.                 &info,
  108.                 Map_Offset,
  109.                 sizeof (MapDatum)
  110.             );
  111.         if (status != noErr)
  112.             printf("Error %d\n", status);
  113.         dms(info.latitude, "Latitude", "NS");
  114.         dms(info.longitude,
  115.                 "Longitude", "EW");
  116.         hms(info.timezone, "Zone");
  117. #endif
  118.     } while (getchar() != 'q');
  119. }
  120.  
  121. /*
  122.  * Convert to degrees/minutes/seconds.
  123.  */
  124. void
  125. dms(raw_value, what, zone)
  126. long            raw_value;
  127. char            *what;
  128. char            *zone;
  129. {
  130.     register long    value;
  131.     register long    degree, minute, second;
  132.     int                west;
  133.  
  134.     static long    one_degree =
  135.         (0x80000000L / 180L);
  136.     static long    one_minute =
  137.         (0x80000000L / (180L * 60L));
  138.     static long    one_second =
  139.         (0x80000000L / (180L * 60L * 60L));
  140.  
  141.     value = raw_value;
  142.     degree = value / one_degree;
  143.     value -= (degree * one_degree);
  144.     minute = value / one_minute;
  145.     value -= (minute * one_minute);
  146.     second = value / one_second;
  147.     if ((west = (raw_value < 0))) {
  148.         degree = (-degree);
  149.         minute = (-minute);
  150.         second = (-second);
  151.     }    
  152.     printf(
  153.         "%08lx: %3ld°%02ld'%02ld\" %c %s\n",
  154.         raw_value, degree, minute, second,
  155.         zone[west], what
  156.     );
  157. }
  158.  
  159. /*
  160.  * Convert time to hours:minutes:seconds.
  161.  */
  162. void
  163. hms(timezone, what)
  164. long            timezone;
  165. char            *what;
  166. {
  167.     register long    value;
  168.     register long    hour, minute, second;
  169.     int                west;
  170.  
  171.     static long    one_hour    = (60L * 60L);
  172.     static long    one_minute    = (60L);
  173.  
  174.     if (timezone & 0xFF000000) {
  175.         printf("timezone high byte %08lx\n",
  176.                 timezone);
  177.         timezone &= 0x00FFFFFF;
  178.     }
  179.     /*
  180.      * Propogate the sign bit from bit 23
  181.      * to bit 31 if West of UTC.
  182.      */
  183.     if ((timezone & 0x00800000) != 0)
  184.         timezone |= 0xFF000000;    
  185.     value     = timezone;
  186.     hour     = value / one_hour;
  187.     value     -= (hour * one_hour);
  188.     minute     = value / one_minute;
  189.     value    -= (minute * one_minute);
  190.     second     = value;
  191.     if ((west = (timezone < 0))) {
  192.         hour = (-hour);
  193.         minute = (-minute);
  194.         second = (-second);
  195.     }     
  196.     printf(
  197.         "%08lx: %3ld.%02ld.%02ld  %c %s\n",
  198.         timezone, hour, minute, second,
  199.         "EW"[west], what
  200.     );
  201. }
  202.  
  203. /*
  204.  * Read data from the clock parameter ram.
  205.  * The start parameter specifies the offset
  206.  * within the parameter ram where the read
  207.  * is to start. The count parameter specifies
  208.  * the number of bytes to read.
  209.  */
  210. OSErr
  211. read_param_ram(address, start, count)
  212. void        *address;    /* Result loc    */
  213. int            start;        /* Ram start    */
  214. int            count;        /* Read size    */
  215. {
  216.     /*
  217.      * Put the count into the high word of
  218.      * D0, the pRRAM start address into the
  219.      * low word of D0, the Macintosh memory
  220.      * address in A0, and trap to ROM.
  221.      * _ReadXPRam returns noErr on success
  222.      * and prInitErr on failure.
  223.       */
  224.     asm {
  225.         move.w        count,D0
  226.         swap        D0
  227.         move.w        start,D0
  228.         movea.l        address,A0
  229.         dc.w        _ReadXPRam
  230.         return
  231.     }
  232. }
  233.  
  234.